/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package create_view_modify;

import cse308.entities.Altcoursecoordinators;
import cse308.entities.AltcoursecoordinatorsPK;
import cse308.entities.Courseinfo;
import cse308.entities.Courseoutcome;
import cse308.entities.Degreeprogram;
import cse308.GUIUtilityClass;
import cse308.UserSessionBean;
import cse308.entities.Users;
import cse308.helper_classes.CourseClass;
import cse308.helper_classes.DegreeProgramClass;
import cse308.helper_classes.GeneralTest;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;

/**
 *
 * @author Aaron
 */
@ManagedBean(name = "courseBean")
@SessionScoped
public class CourseBean implements Serializable {

    @ManagedProperty(value = "#{userSessionBean}")
    UserSessionBean userSessionBean;
    @ManagedProperty(value = "#{gUIUtilityClass}")
    private GUIUtilityClass utilities;
    private String title;
    private String name;
    private String identifier;
    private String courseCoordinator;
    private List<DegreeProgramClass> allDegreePrograms = new LinkedList();
    private List<String> degreeProgram = new ArrayList();
    private List<Courseoutcome> allCourseOutcomes = new LinkedList();
    private List<String> courseOutcomes = new ArrayList();
    private List<Altcoursecoordinators> allAltCourseCoordinators = new LinkedList();
    private List<String> altCourseCoordinators = new ArrayList();
    private final static Logger LOG = Logger.getLogger(GUIUtilityClass.class.getName());
    private List<CourseClass> courseClasses = (List<CourseClass>) new ArrayList();
    private List<Users> userList = (List<Users>) new ArrayList();
    private byte[] fileStuff;

    public CourseBean() {
    }

    public List<CourseClass> getCourseClasses() {
        return courseClasses;
    }

    public List<Users> getUserList() {
        return userList;
    }

    public void setUserList(List<Users> userList) {
        this.userList = userList;
    }

    
    public byte[] getFileStuff() {
        return fileStuff;
    }

    public void setFileStuff(byte[] fileStuff) {
        this.fileStuff = fileStuff;
    }

    public void setCourseClasses(List<CourseClass> courseClasses) {
        this.courseClasses = courseClasses;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getIdentifier() {
        return identifier;
    }

    public void setIdentifier(String identifier) {
        this.identifier = identifier;
    }

    public String getCourseCoordinator() {
        return courseCoordinator;
    }

    public void setCourseCoordinator(String courseCoordinator) {
        this.courseCoordinator = courseCoordinator;
    }

    public String createCourse() {


        EntityManagerFactory emf = Persistence.createEntityManagerFactory("CSE_308_ABETPU");
        EntityManager em = emf.createEntityManager();

        em.getTransaction().begin();
        Courseinfo course = new Courseinfo();
        LOG.info("Created new Course entity");

        course.setIdentifier(this.identifier);
        course.setCoursecoordinator(this.courseCoordinator);
        course.setCoursename(name);
        if (utilities.checkPK(course)) {
            FacesMessage message = new FacesMessage();
            message.setDetail(GUIUtilityClass.createWarning);
            FacesContext.getCurrentInstance().addMessage("form", message);
            return "";
        }
        for (String i : this.degreeProgram) {
            List<Degreeprogram> dpl = em.createNamedQuery("Degreeprogram.findByIdentifier").setParameter("identifier", i).getResultList();
            if (dpl.size() > 0) {
                Degreeprogram dp = dpl.get(0);
                dp.getCourseinfoCollection().add(course);
                course.getDegreeprogramCollection().add(dp);
                em.persist(em.merge(dp));
            }
            //Coursetodegree ctd = new Coursetodegree(this.name, i);
            //em.persist(ctd);
        }
        for (String i : altCourseCoordinators) {
            //StringTokenizer st = new StringTokenizer(i);
            //String s1 = st.nextToken();
            String s2 = this.identifier;
            AltcoursecoordinatorsPK primaryKey = new AltcoursecoordinatorsPK(s2, i);
            Altcoursecoordinators accl = em.find(Altcoursecoordinators.class, primaryKey);
            if (accl !=null) {
                accl.setCourseinfo(course);
                course.getAltcoursecoordinatorsCollection().add(accl);
                em.persist(accl);
            }
        }
        for (String i : this.courseOutcomes) {
            List<Courseoutcome> col = em.createNamedQuery("Courseoutcome.findByIdentifier").setParameter("identifier", i).getResultList();
            if (col.size() > 0) {
                Courseoutcome co = col.get(0);
                co.setCourseidentifier(course);
                course.getCourseoutcomeCollection().add(co);
                em.persist(em.merge(co));
            }
        }
        //em.persist(course);
        em.getTransaction().commit();

        return "welcome";
    }

    public String createCourses() {
        allDegreePrograms = new LinkedList();
        allAltCourseCoordinators = new LinkedList();
        allCourseOutcomes = new LinkedList();
        userList = new ArrayList();
        this.courseClasses = new ArrayList();
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("CSE_308_ABETPU");
        EntityManager em = emf.createEntityManager();
        List<Degreeprogram> ge = em.createNamedQuery("Degreeprogram.findAll").getResultList();
        for (Degreeprogram dp : ge) {
            this.allDegreePrograms.add(new DegreeProgramClass(dp));
        }
        List<Altcoursecoordinators> alt = em.createNamedQuery("Altcoursecoordinators.findAll").getResultList();
        for (Altcoursecoordinators al : alt) {
            this.allAltCourseCoordinators.add(al);
        }
        List<Courseoutcome> col = em.createNamedQuery("Courseoutcome.findAll").getResultList();
        for (Courseoutcome co : col) {
            this.allCourseOutcomes.add(co);
        }
        List<Users> u1 = em.createNamedQuery("Users.findAll").getResultList();
        for(Users u : u1){
            this.userList.add(u);
        }
        this.courseCoordinator = null;
        return "CreateCourse";
    }

    public String viewCourses() {
        this.courseClasses = new ArrayList();
        title = "Courses";
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("CSE_308_ABETPU");
        EntityManager em = emf.createEntityManager();
        Query cinfos = em.createNamedQuery("Courseinfo.findAll");
        List<Courseinfo> results = (List<Courseinfo>) cinfos.getResultList();
        /*       for (Courseinfo i : results) {
         for(Degreeprogram j : i.getDegreeprogramCollection()){
         for (Users k : j.getUsersCollection()) {
         if(k.getUsername().equalsIgnoreCase(userSessionBean.getUsername())){
         CourseClass currentCourse = new CourseClass(i);
         courseClasses.add(currentCourse);
         }
         }
         }
         }*/

        List<String> path = new ArrayList();
        path.add(Degreeprogram.class.getSimpleName());
        path.add(Users.class.getSimpleName());
        for (Courseinfo i : results) {
            if (GUIUtilityClass.isUserRole(path, 0, i)) {
                courseClasses.add(new CourseClass(i));
            }
        }
        //List<Coursetodegree> degreeProgramResult = (List<Coursetodegree>) degreeprograms.getResultList();
        Query altccs = em.createNamedQuery("Altcoursecoordinators.findAll");
        List<Altcoursecoordinators> altCCsResult = (List<Altcoursecoordinators>) altccs.getResultList();
        Query courseoutcomes = em.createNamedQuery("Courseoutcome.findAll");
        List<Courseoutcome> courseOutcomeResult = (List<Courseoutcome>) courseoutcomes.getResultList();
        for (CourseClass i : courseClasses) {
            Collection<Degreeprogram> dp = ((Courseinfo) i.findCorrespondingEntity()).getDegreeprogramCollection();
            Map<String, String> mapForDegree = new HashMap();
            for (Degreeprogram dp2 : dp) {
                String degreeProgram3 = dp2.getIdentifier();
                mapForDegree.put(degreeProgram3, degreeProgram3);
            }


            i.setDegreePrograms(mapForDegree);

            Map<String, String> mapForAltCoor = new HashMap();
            for (int j = 0; j < altCCsResult.size(); j++) {
                if (altCCsResult.get(j).getAltcoursecoordinatorsPK().getCourseidentifier().equals(i.getIdentifier())) {
                    String altCourseCoordinator = altCCsResult.get(j).getAltcoursecoordinatorsPK().getAltcoordinator();
                    mapForAltCoor.put(altCourseCoordinator, altCourseCoordinator);
                }
            }
            i.setAltCourseCoordinators(mapForAltCoor);

            Map<String, String> mapForCourseOutcomes = new HashMap();
            Collection<Courseoutcome> courseOutcomes2= ((Courseinfo) i.findCorrespondingEntity()).getCourseoutcomeCollection();
            for (Courseoutcome co : courseOutcomes2) {
                mapForCourseOutcomes.put(co.getIdentifier(), co.getIdentifier());
            }
           

            i.setCourseOutcomes(mapForCourseOutcomes);
        }

        LOG.info(
                "Shows all courses in DB");

        return "viewCoursePage";
    }

    public String modifyEntry() {
        List<String> setMethods = new ArrayList();
        setMethods.add("setOwnDegreePrograms");
        setMethods.add("setOwnCourseOutcomes");
        setMethods.add("setOwnAltCourseCoordinators");

        List<String> setMethods2 = new ArrayList();
        setMethods2.add("setAllDegreePrograms");
        setMethods2.add("setAllCourseOutcomes");
        setMethods2.add("setAllAltCourseCoordinators");

        List<String> associatedEntities = new ArrayList();
        associatedEntities
                .add(Degreeprogram.class
                .getCanonicalName());
        associatedEntities.add(Courseoutcome.class
                .getCanonicalName());
        associatedEntities.add(Altcoursecoordinators.class
                .getCanonicalName());

        List<String> associatedClasses = new ArrayList();

        associatedClasses.add(DegreeProgramClass.class
                .getCanonicalName());
        associatedClasses.add(Courseoutcome.class
                .getCanonicalName());
        associatedClasses.add(Altcoursecoordinators.class
                .getCanonicalName());

        try {
            this.courseClasses = (List) this.utilities.generalizeModify(Courseinfo.class.getCanonicalName(),
                    CourseClass.class.getCanonicalName(),
                    associatedClasses, associatedEntities, setMethods, setMethods2);
        } catch (ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
            Logger.getLogger(CourseBean.class.getName()).log(Level.SEVERE, null, ex);
        }


        return "ModifyCourses";
    }

    public String saveEntry() {
        ArrayList<GeneralTest> gt = new ArrayList();
        for (CourseClass c : this.courseClasses) {
            gt.add(c);
        }
        List<String> associatedEntities = new ArrayList();
        associatedEntities.add(Degreeprogram.class.getSimpleName());
        associatedEntities.add(Courseoutcome.class.getSimpleName());
        associatedEntities.add(Altcoursecoordinators.class.getSimpleName());
        if (utilities.checkOneToMany(gt, 0)) {
            FacesMessage message = new FacesMessage();
            message.setDetail("For Course outcome and Alternate Course Coordinate, you can only associate an item with one Course Offering");
            FacesContext.getCurrentInstance().addMessage("form", message);
            return "";
        }

        try {
            boolean success = this.utilities.generalizedSave(Courseinfo.class.getCanonicalName(), gt, associatedEntities);
            if (!success) {
                FacesMessage message = new FacesMessage();
                message.setDetail(GUIUtilityClass.duplicateWarning);
                FacesContext.getCurrentInstance().addMessage("form", message);
                return "";
            }
        } catch (SecurityException | NoSuchFieldException | IllegalArgumentException | IllegalAccessException | NoSuchMethodException | InvocationTargetException | ClassNotFoundException | InstantiationException ex) {
            Logger.getLogger(CourseBean.class.getName()).log(Level.SEVERE, null, ex);
        }
        return "ModifyCourses";
    }

    public UserSessionBean getUserSessionBean() {
        return userSessionBean;
    }

    public void setUserSessionBean(UserSessionBean userSessionBean) {
        this.userSessionBean = userSessionBean;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public List<DegreeProgramClass> getAllDegreePrograms() {
        return allDegreePrograms;
    }

    public void setAllDegreePrograms(List<DegreeProgramClass> allDegreePrograms) {
        this.allDegreePrograms = allDegreePrograms;
    }

    public List<Courseoutcome> getAllCourseOutcomes() {
        return allCourseOutcomes;
    }

    public void setAllCourseOutcomes(List<Courseoutcome> allCourseOutcomes) {
        this.allCourseOutcomes = allCourseOutcomes;
    }

    public List<Altcoursecoordinators> getAllAltCourseCoordinators() {
        return allAltCourseCoordinators;
    }

    public void setAllAltCourseCoordinators(List<Altcoursecoordinators> allAltCourseCoordinators) {
        this.allAltCourseCoordinators = allAltCourseCoordinators;
    }

    public List<String> getDegreeProgram() {
        return degreeProgram;
    }

    public void setDegreeProgram(List<String> degreeProgram) {
        this.degreeProgram = degreeProgram;
    }

    public List<String> getCourseOutcomes() {
        return courseOutcomes;
    }

    public void setCourseOutcomes(List<String> courseOutcomes) {
        this.courseOutcomes = courseOutcomes;
    }

    public List<String> getAltCourseCoordinators() {
        return altCourseCoordinators;
    }

    public void setAltCourseCoordinators(List<String> altCourseCoordinators) {
        this.altCourseCoordinators = altCourseCoordinators;
    }

    public GUIUtilityClass getUtilities() {
        return utilities;
    }

    public void setUtilities(GUIUtilityClass utilities) {
        this.utilities = utilities;
    }
}
